package com.sky.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.*;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.*;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.OrdersService;
import com.sky.service.ShoppingCartService;
import com.sky.utils.WeChatPayUtil;
import com.sky.vo.OrderPaymentVO;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class OrdersServiceImpl implements OrdersService {

    @Autowired
    private OrdersMapper ordersMapper;

    @Autowired
    private AddressBookMapper addressBookMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShoppingCartMapper shoppingCartMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private WeChatPayUtil weChatPayUtil;

    @Autowired
    private ShoppingCartService shoppingCartService;

    @Autowired
    private WebSocketServer webSocketServer;

    /**
     * 用户下单--最终目的，将订单数据存入表中（orders、order_detail）
     * @param dto
     * @return
     */
    @Override
    @Transactional   //开启事务
    public OrderSubmitVO submit(OrdersSubmitDTO dto) {
        //查询地址表，获取收货人信息
        AddressBook addressBook = addressBookMapper.getById(dto.getAddressBookId());
        if(addressBook == null){
            throw new OrderBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }

        //根据用户id查询用户表，获取用户相关信息
        Long userId =BaseContext.getCurrentId();
        User user = userMapper.selectById(userId);
        if(user == null){
            throw new OrderBusinessException(MessageConstant.USER_NOT_LOGIN);
        }

        //查询购物车列表数据--只查询自己名下的购物车数据
        List<ShoppingCart> cartList = shoppingCartMapper.list(userId);
        if(cartList == null || cartList.size() == 0){
            throw new OrderBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }

        //1.构造订单数据，存入orders表中
        Orders orders = new Orders();
        //拷贝属性值
        BeanUtils.copyProperties(dto, orders);
        //补充缺失的属性值
        orders.setNumber(System.currentTimeMillis() + ""); //订单编号
        orders.setStatus(Orders.PENDING_PAYMENT);  //订单状态-待付款
        orders.setUserId(userId); //用户id-下单人id
        orders.setOrderTime(LocalDateTime.now()); //下单时间
        orders.setPayStatus(Orders.UN_PAID);  //支付状态-未支付
        orders.setPhone(addressBook.getPhone());  //收货人电话
        orders.setAddress(addressBook.getDetail()); //收货人的详细地址
        orders.setConsignee(addressBook.getConsignee());  //收货人
        orders.setUserName(user.getName());  //下单人
        ordersMapper.insert(orders);
        log.info("订单id：{}",orders.getId());

        //2.构造订单明细数据，存入order_detail表中
        ArrayList<OrderDetail> orderDetailList = new ArrayList<>();
        //循环遍历购物车列表数据，构造订单明细
        cartList.forEach(cart -> {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail,"id");
            //关联订单id
            orderDetail.setOrderId(orders.getId());
            orderDetailList.add(orderDetail);
        });
        //批量插入订单明细数据
        orderDetailMapper.insertBatch(orderDetailList);

        //3.清空购物车--删除自己名下的购物车列表数据
        shoppingCartMapper.delete(userId);

        //4.构造OrderSubmitVO对象并返回
        return OrderSubmitVO.builder()
                .id(orders.getId())
                .orderNumber(orders.getNumber())
                .orderAmount(orders.getAmount())
                .orderTime(orders.getOrderTime())
                .build();
    }

    /**
     * 订单支付
     * @param ordersPaymentDTO
     * @return
     */
    public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
//        // 当前登录用户id
//        Long userId = BaseContext.getCurrentId();
//        User user = userMapper.selectById(userId);
//
//        //调用微信支付接口，生成预支付交易单
//        JSONObject jsonObject = weChatPayUtil.pay(
//                ordersPaymentDTO.getOrderNumber(), //商户订单号
//                new BigDecimal(0.01), //支付金额，单位 元
//                "苍穹外卖订单", //商品描述
//                user.getOpenid() //微信用户的openid
//        );
//
//        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
//            throw new OrderBusinessException("该订单已支付");
//        }
//
//        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
//        vo.setPackageStr(jsonObject.getString("package"));
//
//        return vo;
        paySuccess(ordersPaymentDTO.getOrderNumber());
        return new OrderPaymentVO();
    }

    /**
     * 支付成功，修改订单状态
     * @param outTradeNo
     */
    public void paySuccess(String outTradeNo) {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();

        // 根据订单号查询当前用户的订单
        Orders ordersDB = ordersMapper.getByNumberAndUserId(outTradeNo, userId);

        // 根据订单id更新订单的状态、支付方式、支付状态、结账时间
        Orders orders = Orders.builder()
                .id(ordersDB.getId())
                .status(Orders.TO_BE_CONFIRMED)
                .payStatus(Orders.PAID)
                .checkoutTime(LocalDateTime.now())
                .build();

        ordersMapper.update(orders);

        // 通过WebSocket向客户端推送消息，type orderId content
        HashMap map = new HashMap();
        map.put("type", 1); //1代表来单提醒，2代表客户催单
        map.put("orderId", ordersDB.getId());
        map.put("content", "订单号："+ outTradeNo);

        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

    /**
     * 用户端-查询历史订单列表
     * @param dto 订单分页查询条件，包含页码、每页大小等参数
     * @return PageResult 分页结果对象，包含订单总数和当前页的订单数据列表
     */
    @Override
    public PageResult historyOrders(OrdersPageQueryDTO dto) {
        //设置用户id
        dto.setUserId(BaseContext.getCurrentId());

        //设置分页参数
        PageHelper.startPage(dto.getPage(), dto.getPageSize());

        List<OrderVO> orderVO = new ArrayList();
        //查询orders表中订单的基本信息
        Page<Orders> page =ordersMapper.list(dto);
        //遍历订单列表，查询每个订单的详细信息
        for (Orders order : page) {
            //查询订单明细表order_detail
            List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(order.getId());
            OrderVO vo = new OrderVO();
            BeanUtils.copyProperties(order, vo);
            vo.setOrderDetailList(orderDetailList);
            orderVO.add(vo);
        }
        return new PageResult(page.getTotal(),orderVO);
    }

    /**
     * 根据订单ID查询订单详情
     *
     * @param id 订单ID
     * @return 订单详情信息
     */
    @Override
    public OrderVO orderDetail(Long id) {
        //进行订单表和订单详细表的联合查询
        return ordersMapper.orderDetail(id);
    }

    /**
     * 用户取消指定订单
     * @param id 订单ID，用于标识需要取消的订单
     */
    @Override
    public void cancel(Long id) throws Exception {
        log.info("取消订单：{}", id);
        OrderVO vo = ordersMapper.orderDetail(id);
        //订单不存在，订单不是待支付或待接单的状态，不能取消订单
        if(vo==null||vo.getStatus()>2){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //订单状态为待接单状态，需要进行退款操作
        if(vo.getPayStatus()==Orders.PAID&&vo.getStatus()==Orders.TO_BE_CONFIRMED){
            //调用微信支付接口，进行支付退款
//            String refund = weChatPayUtil.refund(vo.getNumber(), vo.getNumber(),
//                    new BigDecimal(0.01), new BigDecimal(0.01));
//            log.info("订单取消，进行退款操作：{}", refund);
            //支付支付状态修改为退款
            ordersMapper.updatePayStatus(id,Orders.REFUND);
        }
        Orders order = new Orders();
        // 更新订单状态为取消状态
        order.setId(id);
        order.setStatus(Orders.CANCELLED);
        order.setCancelReason("用户取消");
        order.setCancelTime(LocalDateTime.now());
        ordersMapper.update(order);
    }

    /**
     * 再来一单功能，将指定订单中的菜品重新添加到购物车中
     * @param id 订单ID，用于查询订单详细信息
     */
    @Override
    public void repetition(Long id) {
        //根据订单id查询订单的信息
        OrderVO order = ordersMapper.orderDetail(id);
        List<OrderDetail> orderDetailList = order.getOrderDetailList();

        //调用添加菜品到购物车的方法，将订单中的菜品数据添加到购物车中（需要ShoppingCartDTO对象作为参数，dishId,setmealId,dishFlavor）
        for (OrderDetail orderDetail : orderDetailList) {
            ShoppingCartDTO cartDTO = new ShoppingCartDTO();
            cartDTO.setDishId(orderDetail.getDishId());
            cartDTO.setSetmealId(orderDetail.getSetmealId());
            cartDTO.setDishFlavor(orderDetail.getDishFlavor());
            shoppingCartService.addCart(cartDTO);
        }
    }

    /**
     * 根据条件查询订单分页数据
     * @param dto 订单分页查询条件DTO对象，包含页码、每页大小等查询参数
     * @return PageResult 分页结果对象，包含总记录数和当前页的订单VO列表
     */
    @Override
    public PageResult conditionSearch(OrdersPageQueryDTO dto) {
        //设置分页参数
        PageHelper.startPage(dto.getPage(), dto.getPageSize());

        // 查询订单列表并转换为VO对象
        List<OrderVO> orderVOList = new ArrayList<>();
        Page<Orders> list = ordersMapper.list(dto);
        for (Orders order : list) {
            OrderVO vo = new OrderVO();
            BeanUtils.copyProperties(order, vo);

            // 获取订单详情并拼接菜品名称
            List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(order.getId());
            StringBuilder stringBuilder = new StringBuilder();
            for(OrderDetail orderDetail : orderDetailList){
                stringBuilder.append(orderDetail.getName());
            }
            vo.setOrderDishes(stringBuilder.toString());
            orderVOList.add(vo);
        }

        return new PageResult(list.getTotal(), orderVOList);
    }

    /**
     * 统计订单状态数据
     *
     * @return OrderStatisticsVO 订单统计信息对象，包含待确认、已确认、派送中三种状态的订单数量
     */
    @Override
    public OrderStatisticsVO statistics() {
        // 查询各种状态的订单数量
        Integer toBeConfirmed=ordersMapper.countByStatus(Orders.TO_BE_CONFIRMED);
        Integer confirmed=ordersMapper.countByStatus(Orders.CONFIRMED);
        Integer deliveryInProgress=ordersMapper.countByStatus(Orders.DELIVERY_IN_PROGRESS);

        // 封装统计结果到VO对象
        OrderStatisticsVO vo=new OrderStatisticsVO();
        vo.setToBeConfirmed(toBeConfirmed);
        vo.setConfirmed(confirmed);
        vo.setDeliveryInProgress(deliveryInProgress);
        return vo;
    }

    /**
     * 接单
     * @param dto 订单确认参数对象
     */
    @Override
    public void confirm(OrdersConfirmDTO dto) {
        ordersMapper.updateStatus(dto.getId(),Orders.CONFIRMED);
    }

    /**
     * 拒绝订单处理方法
     *
     * @param dto 订单拒绝信息传输对象，包含订单ID和拒绝原因
     * @throws Exception 当订单状态异常或退款操作失败时抛出异常
     */
    @Override
    public void rejection(OrdersRejectionDTO dto) throws Exception {
        log.info("订单拒绝：{}", dto);
        // 查询订单
        OrderVO vo = ordersMapper.orderDetail(dto.getId());

        // 判断订单状态，如果订单状态不是待接单的状态，则抛出业务异常
        if(vo==null||vo.getStatus()!=Orders.TO_BE_CONFIRMED){
            new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //判断订单支付状态，如果订单已经支付，需要进行退款操作
        Integer payStatus = vo.getPayStatus();
        if(payStatus==Orders.PAID){
//            String refund = weChatPayUtil.refund(vo.getNumber(), vo.getNumber(),
//                    new BigDecimal(0.01), new BigDecimal(0.01));
//            log.info("订单拒绝，进行退款操作：{}", refund);
            // 支付状态修改为退款
            ordersMapper.updatePayStatus(dto.getId(),Orders.REFUND);
        }
        Orders order = new Orders();
        // 更新订单状态为订单拒绝状态
        order.setId(dto.getId());
        order.setStatus(Orders.CANCELLED);
        order.setRejectionReason(dto.getRejectionReason());
        order.setCancelTime(LocalDateTime.now());
        ordersMapper.update(order);
    }

    /**
     * 管理端取消订单
     *
     * @param dto 订单取消信息传输对象，包含订单ID和取消原因
     * @throws Exception 可能抛出的异常
     */
    @Override
    public void cancelByAdmin(OrdersCancelDTO dto) throws Exception {
        // 查询订单详情
        OrderVO vo = ordersMapper.orderDetail(dto.getId());

        if(vo==null||vo.getStatus()>3){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        // 如果订单已支付，则进行退款操作
        if(vo.getPayStatus()==Orders.PAID){
//            String refund = weChatPayUtil.refund(vo.getNumber(), vo.getNumber(),
//                    new BigDecimal(0.01), new BigDecimal(0.01));
//            log.info("订单取消，进行退款操作：{}", refund);
            ordersMapper.updatePayStatus(dto.getId(),Orders.REFUND);
        }

        // 更新订单状态为已取消
        Orders order = new Orders();
        order.setId(dto.getId());
        order.setStatus(Orders.CANCELLED);
        order.setCancelReason(dto.getCancelReason());
        order.setCancelTime(LocalDateTime.now());
        ordersMapper.update(order);
    }

    /**
     * 订单配送处理方法
     * @param id 订单ID
     */
    @Override
    public void delivery(Long id) {
        //查询订单的详细信息
        OrderVO vo = ordersMapper.orderDetail(id);
        if(vo==null||vo.getStatus()!=Orders.CONFIRMED){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }
        Orders order = new Orders();
        order.setId(id);
        order.setStatus(Orders.DELIVERY_IN_PROGRESS);
        ordersMapper.update(order);
    }

    /**
     * 完成订单
     * 将指定ID的订单状态更新为已完成状态
     *
     * @param id 订单ID
     */
    @Override
    public void complete(Long id) {
        //查询订单的详细信息
        OrderVO vo = ordersMapper.orderDetail(id);

        //验证订单是否存在且状态为配送中
        if(vo==null||vo.getStatus()!=Orders.DELIVERY_IN_PROGRESS){
            throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
        }

        //更新订单状态为已完成
        Orders order = new Orders();
        order.setId(id);
        order.setStatus(Orders.COMPLETED);
        ordersMapper.update(order);
    }

    /**
     * 发送催单提醒通知
     * @param id 订单ID
     */
    @Override
    public void reminder(Long id) {
        //根据id查询订单
        OrderVO orderVO = ordersMapper.orderDetail(id);

        //校验订单是否存在
        if(orderVO==null){
            throw new OrderBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }

        //构建提醒消息内容
        HashMap map = new HashMap();
        map.put("type",2); //1表示来单提醒，2表示客户催单
        map.put("orderId",id);
        map.put("content","订单号："+orderVO.getNumber());

        //通过WebSocket向客户端推送消息
        webSocketServer.sendToAllClient(JSON.toJSONString(map));
    }



}
